home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / ck5a189s / ckuus3.c < prev    next >
C/C++ Source or Header  |  1993-06-27  |  40KB  |  1,571 lines

  1. #ifndef NOICP
  2.  
  3. /*  C K U U S 3 --  "User Interface" for Unix Kermit, part 3  */
  4.  
  5. /*
  6.   Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
  7.   Columbia University Academic Information Systems, New York City.
  8.  
  9.   Copyright (C) 1985, 1993, Trustees of Columbia University in the City of New
  10.   York.  The C-Kermit software may not be, in whole or in part, licensed or
  11.   sold for profit as a software product itself, nor may it be included in or
  12.   distributed with commercial products or otherwise distributed by commercial
  13.   concerns to their clients or customers without written permission of the
  14.   Office of Kermit Development and Distribution, Columbia University.  This
  15.   copyright notice must not be removed, altered, or obscured.
  16. */
  17.  
  18. /*  SET command (but much material has been split off into ckuus7.c). */
  19.  
  20. /*
  21.   Kermit-specific includes.
  22.   Definitions here supersede those from system include files.
  23. */
  24. #include "ckcdeb.h"            /* Debugging & compiler things */
  25. #include "ckcasc.h"            /* ASCII character symbols */
  26. #include "ckcker.h"            /* Kermit application definitions */
  27. #include "ckcxla.h"            /* Character set translation */
  28. #include "ckcnet.h"            /* Network symbols */
  29. #include "ckuusr.h"            /* User interface symbols */
  30.  
  31. /* Variables */
  32.  
  33. extern int size, spsiz, spmax, urpsiz, srvtim, 
  34.   local, server, success,
  35.   flow, binary, delay, parity, escape, what, srvdis,
  36.   turn, duplex, backgrd,
  37.   turnch, bctr, mdmtyp, keep, maxtry, unkcs, network,
  38.   ebqflg, quiet, swcapr, nettype,
  39.   wslotr, lscapr, lscapu,
  40.   carrier, debses,
  41.   cdtimo, nlangs, bgset, pflag, msgflg, dblchar,
  42.   cmdmsk, spsizr, wildxpand, suspend,
  43.   techo, rptena, rptmin,
  44.   xfrcan, xfrchr, xfrnum, pacing;
  45.  
  46. #ifdef TNCODE
  47.   extern int ttnproto;
  48. #endif /* TNCODE */
  49.  
  50. extern char *ccntab[];            /* Names of control chars */
  51. #ifdef CK_SPEED
  52. extern short ctlp[];            /* Control-prefix table */
  53. #endif /* CK_SPEED */
  54.  
  55. #ifndef NOSCRIPT
  56. extern int secho;            /* Whether SCRIPT cmd should echo */
  57. #endif /* NOSCRIPT */
  58.  
  59. #ifdef DCMDBUF
  60. extern char *atmbuf;
  61. #else
  62. extern char atmbuf[];
  63. #endif /* DCMDBUF */
  64.  
  65. #ifndef NOSPL
  66. #ifdef DCMDBUF
  67. extern int *count, *takerr, *merror, *inpcas;
  68. #else
  69. extern int count[], takerr[], merror[], inpcas[];
  70. #endif /* DCMDBUF */
  71. extern int mecho;            /* Macro echo */
  72. #else
  73. extern int takerr[];
  74. #endif /* NOSPL */
  75.  
  76.  
  77. extern int bigsbsiz, bigrbsiz;        /* Packet buffers */
  78.  
  79. extern long speed;            /* Terminal speed */
  80.  
  81. extern CHAR sstate;            /* Protocol start state */
  82. extern CHAR myctlq;            /* Control-character prefix */
  83. extern CHAR myrptq;            /* Repeat-count prefix */
  84. extern CHAR mystch, seol;        /* Packet start and end chars */
  85. extern char ttname[];            /* Communication device name */
  86. #ifndef MAC
  87. #ifndef NOSETKEY
  88. extern KEY *keymap;            /* Character map for SET KEY (1:1)  */
  89. extern MACRO *macrotab;            /* Macro map for SET KEY (1:string) */
  90. #ifdef OS2
  91. int wideresult;                         /* for SET KEY, wide OS/2 scan codes */
  92. #endif /* OS2 */
  93. #endif /* NOSETKEY */
  94. #endif /* MAC */
  95.  
  96. #ifndef NOCSETS
  97. /* system-independent character sets, defined in ckcxla.[ch] */
  98. extern struct csinfo tcsinfo[];
  99. extern struct langinfo langs[];
  100.  
  101. /* Other character-set related variables */
  102. extern int tcharset, tslevel, language;
  103. #endif /* NOCSETS */ 
  104.  
  105. /* Declarations from cmd package */
  106.  
  107. #ifdef DCMDBUF
  108. extern char *cmdbuf;            /* Command buffer */
  109. extern char *line;
  110. extern char *tmpbuf;
  111. #else
  112. extern char cmdbuf[];            /* Command buffer */
  113. extern char line[];            /* Character buffer for anything */
  114. extern char tmpbuf[];
  115. #endif /* DCMDBUF */
  116.  
  117. /* From main ckuser module... */
  118.  
  119. extern char *tp, *lp;            /* Temporary buffer */
  120.  
  121. extern int tlevel;            /* Take Command file level */
  122.  
  123. #ifndef NOSPL
  124. extern int cmdlvl;            /* Overall command level */
  125. #endif /* NOSPL */
  126.  
  127. #ifdef UNIX
  128. extern int sessft;            /* Session-log file type */
  129. #endif /* UNIX */
  130.  
  131.  
  132. #ifdef VMS
  133. int vms_msgs = 1;            /* SET MESSAGES */
  134. #endif /* VMS */
  135.  
  136. /* Keyword tables for SET commands */
  137.  
  138. #ifdef CK_SPEED
  139. struct keytab ctltab[] = {
  140.     "prefixed",   1, 0,            /* Note, the values are important. */
  141.     "unprefixed", 0, 0
  142. };
  143. #endif /* CK_SPEED */
  144.  
  145. #ifndef NOSPL
  146. struct keytab outptab[] = {        /* SET OUTPUT parameters */
  147.     "pacing", 0, 0            /* only one so far... */
  148. };
  149. #endif /* NOSPL */
  150.  
  151. struct keytab chktab[] = {        /* Block check types */
  152.     "1", 1, 0,                /* 1 =  6-bit checksum */
  153.     "2", 2, 0,                /* 2 = 12-bit checksum */
  154.     "3", 3, 0,                /* 3 = 16-bit CRC */
  155.     "blank-free-2", 4, 0        /* B = 12-bit checksum, no blanks */
  156. };
  157.  
  158. struct keytab rpttab[] = {        /* SET REPEAT */
  159.     "counts",    0, 0,            /* On or Off */
  160. #ifdef COMMENT
  161.     "minimum",   1, 0,            /* Threshhold */
  162. #endif /* COMMENT */
  163.     "prefix",    2, 0            /* Repeate-prefix character value */
  164. };
  165.  
  166. /* For SET MODEM */
  167.  
  168. struct keytab autotab[] = {
  169.     "changes-speed", 1, 0,
  170.     "matches-speed", 0, 0
  171. };
  172.  
  173. /* For SET CARRIER */
  174.  
  175. struct keytab crrtab[] = {
  176.     "auto", CAR_AUT, 0,
  177.     "off",  CAR_OFF, 0,
  178.     "on",   CAR_ON, 0
  179. };
  180. int ncrr = 3;
  181.  
  182. /* For SET DEBUG */
  183.  
  184. struct keytab dbgtab[] = {
  185.     "off",     0,  0,
  186.     "on",      1,  0,
  187.     "session", 2,  0
  188. };
  189. int ndbg = 3;
  190.  
  191. /* Transmission speeds */
  192.  
  193. /* Note, the values are encoded in cps rather than bps because 19200 and */
  194. /* higher are too big for some ints.  All but 75bps are multiples of ten. */
  195. /* Result of lookup in this table must be multiplied by 10 to get actual */
  196. /* speed in bps.  If this number is 70, it must be changed to 75. */
  197. /* If it is 888, this means 75/1200 split speed.  134.5 (IBM 2741) is not */
  198. /* supported, and split speed is not possible in AT&T UNIX. */ 
  199.  
  200. /* The values are generic, rather than specific to UNIX.  We can't use */
  201. /* B75, B1200, B9600, etc, because non-UNIX versions of C-Kermit will not */
  202. /* necessarily have these symbols defined. */
  203.  
  204. /* Like all other keytabs, this one must be in "alphabetical" order, */
  205. /* rather than numeric order. */ 
  206.  
  207. struct keytab spdtab[] = {
  208.     "0",      0,  CM_INV,
  209.     "110",   11,  0,
  210. #ifdef HPUX
  211.  "115200",11520,  0,
  212. #else
  213. #ifdef OS2
  214. #ifdef __32BIT__
  215.  "115200",11520,  0,
  216. #endif /* __32BIT__ */
  217. #endif /* OS2 */
  218. #endif /* HPUX */
  219.   "1200",   120,  0,
  220. #ifdef OS2
  221.   "14400", 1440,  0,
  222. #else
  223. #ifdef NEXT
  224.   "14400", 1440,  0,
  225. #endif /* NEXT */
  226. #endif /* OS2 */
  227.   "150",     15,  0,
  228.   "19200", 1920,  0,
  229.   "200",     20,  0,
  230.   "2400",   240,  0,
  231. #ifdef NEXT
  232.   "28800", 2880,  0,
  233. #endif /* NEXT */
  234.   "300",     30,  0,
  235.   "3600",   360,  0,
  236.   "38400", 3840,  0,
  237.   "4800",   480,  0,
  238.   "50",       5,  0,
  239. #ifdef OS2
  240.   "57600", 5760,  0,  
  241. #else
  242. #ifdef HPUX
  243.   "57600", 5760,  0,  
  244. #else
  245. #ifdef NEXT
  246.   "57600", 5760,  0,  
  247. #endif /* NEXT */
  248. #endif /* HPUX */
  249. #endif /* OS2 */
  250.   "600",     60,  0,
  251. #ifdef OS2
  252.   "7200",   720,  0,
  253. #endif /* OS2 */
  254.   "75",       7,  0,
  255. #ifdef ANYBSD
  256.   "75/1200",888,  0,        /* Special code "888" for split speed */
  257. #endif /* ANYBSD */
  258. #ifdef OS2
  259. #ifdef __32BIT__
  260.   "76800", 7680,  0,
  261. #endif /* __32BIT__ */
  262. #endif /* OS2 */
  263.   "9600",   960,  0
  264. };
  265. int nspd = (sizeof(spdtab) / sizeof(struct keytab)); /* how many speeds */
  266.  
  267. #ifndef NOCSETS
  268. extern struct keytab lngtab[];        /* Languages for SET LANGUAGE */
  269. extern int nlng;
  270. #endif /* NOCSETS */
  271.  
  272. /* Duplex keyword table */
  273.  
  274. struct keytab dpxtab[] = {
  275.     "full",      0, 0,
  276.     "half",      1, 0
  277. };
  278.  
  279. /* SET FILE parameters */
  280.  
  281. struct keytab filtab[] = {
  282.     "bytesize",         XYFILS, 0,
  283. #ifndef NOCSETS
  284.     "character-set",    XYFILC, 0,
  285. #endif /* NOCSETS */
  286.     "collision",        XYFILX, 0,
  287.     "display",          XYFILD, 0,
  288.     "incomplete",       XYFILI, 0,
  289. #ifdef VMS
  290.     "label",            XYFILL, 0,
  291. #endif /* VMS */
  292.     "names",            XYFILN, 0,
  293. #ifdef VMS
  294.     "record-length",    XYFILR, 0,
  295. #endif /* VMS */
  296.     "type",             XYFILT, 0,
  297.     "warning",          XYFILW, CM_INV
  298. };
  299. int nfilp = (sizeof(filtab) / sizeof(struct keytab));
  300.  
  301. /* Flow Control */
  302.  
  303. struct keytab flotab[] = {        /* SET FLOW-CONTROL keyword table */
  304. #ifdef CK_DTRCD
  305.     "dtr/cd",   FLO_DTRC, 0,
  306. #endif /* CK_DTRCD */
  307. #ifdef CK_DTRCTS
  308.     "dtr/cts",FLO_DTRT, 0,
  309. #endif /* CK_DTRCTS */
  310.     "keep",     FLO_KEEP, 0,
  311.     "none",     FLO_NONE, 0,
  312. #ifdef CK_RTSCTS
  313.     "rts/cts",  FLO_RTSC, 0,
  314. #endif /* CK_RTSCTS */
  315.     "xon/xoff", FLO_XONX, 0
  316. };
  317. int nflo = (sizeof(flotab) / sizeof(struct keytab));
  318.  
  319. /*  Handshake characters  */
  320.  
  321. struct keytab hshtab[] = {
  322.     "bell", 007, 0,
  323.     "code", 998, 0,
  324.     "cr",   015, 0,
  325.     "esc",  033, 0,
  326.     "lf",   012, 0,
  327.     "none", 999, 0,            /* (can't use negative numbers) */
  328.     "xoff", 023, 0,
  329.     "xon",  021, 0
  330. };
  331. int nhsh = (sizeof(hshtab) / sizeof(struct keytab));
  332.  
  333. struct keytab fttab[] = {        /* File types */
  334. #ifdef VMS
  335.     "b",         XYFT_B, CM_INV|CM_ABR,
  336. #endif /* VMS */
  337.     "binary",    XYFT_B, 0,
  338. #ifdef VMS
  339.     "block",     XYFT_I, CM_INV,
  340.     "image",     XYFT_I, 0,
  341.     "labeled",   XYFT_L, 0,
  342. #endif /* VMS */
  343.     "text",      XYFT_T, 0
  344. };
  345. int nfttyp = (sizeof(fttab) / sizeof(struct keytab));
  346.  
  347. #ifndef NODIAL
  348. extern struct keytab mdmtab[] ;        /* Modem types (in module ckudia.c) */
  349. extern int nmdm;            /* Number of them */
  350. #ifndef MINIDIAL
  351. extern int tbmodel;            /* Telebit model ID */
  352. #endif /* MINIDIAL */
  353. #endif /* NODIAL */
  354.  
  355. #ifdef UNIX
  356. struct keytab wildtab[] = {        /* SET WILDCARD-EXPANSION */
  357.     "kermit",  0, 0,
  358.     "shell",   1, 0
  359. };
  360. #endif /* UNIX */
  361.  
  362. #ifdef NETCONN
  363. extern struct keytab netcmd[];
  364. extern int nnets;
  365. #endif /* NETCONN */
  366.  
  367. #ifdef SUNX25
  368. struct keytab x25tab[] = {
  369.     "call-user-data",    XYUDAT, 0,
  370.     "closed-user-group", XYCLOS, 0,
  371.     "reverse-charge",    XYREVC, 0  
  372. };
  373. int nx25 = (sizeof(x25tab) / sizeof(struct keytab));
  374.  
  375. struct keytab padx3tab[] = {
  376.     "break-action",         PAD_BREAK_ACTION,           0,
  377.     "break-character",      PAD_BREAK_CHARACTER,        0,
  378.     "character-delete",     PAD_CHAR_DELETE_CHAR,       0,
  379.     "cr-padding",           PAD_PADDING_AFTER_CR,       0,
  380.     "discard-output",       PAD_SUPPRESSION_OF_DATA,    0,
  381.     "echo",                 PAD_ECHO,                   0,
  382.     "editing",              PAD_EDITING,                0,
  383.     "escape",               PAD_ESCAPE,                 0,
  384.     "forward",              PAD_DATA_FORWARD_CHAR,      0,
  385.     "lf-padding",           PAD_PADDING_AFTER_LF,       0,
  386.     "lf-insert",            PAD_LF_AFTER_CR,            0,
  387.     "line-delete",          PAD_BUFFER_DELETE_CHAR,     0,
  388.     "line-display",         PAD_BUFFER_DISPLAY_CHAR,    0,
  389.     "line-fold",            PAD_LINE_FOLDING,           0,
  390.     "pad-flow-control",     PAD_FLOW_CONTROL_BY_PAD,    0,
  391.     "service-signals",      PAD_SUPPRESSION_OF_SIGNALS, 0,
  392.     "timeout",              PAD_DATA_FORWARD_TIMEOUT,   0,
  393. /* Speed is read-only */
  394.     "transmission-rate",    PAD_LINE_SPEED,             0,
  395.     "user-flow-control",    PAD_FLOW_CONTROL_BY_USER,   0
  396. };
  397. int npadx3 = (sizeof(padx3tab) / sizeof(struct keytab));
  398. #endif /* SUNX25 */
  399.  
  400. /* Parity keyword table */
  401.  
  402. struct keytab partab[] = {
  403.     "even",    'e', 0,
  404.     "mark",    'm', 0,
  405.     "none",     0 , 0,
  406.     "odd",     'o', 0,
  407.     "space",   's', 0
  408. };
  409. int npar = (sizeof(partab) / sizeof(struct keytab));
  410.  
  411. /* On/Off table */
  412.  
  413. struct keytab onoff[] = {
  414.     "off",       0, 0,
  415.     "on",        1, 0
  416. };
  417.  
  418. struct keytab rltab[] = {
  419.     "local",     1, 0,
  420.     "off",       0, CM_INV,
  421.     "on",        1, CM_INV,
  422.     "remote",    0, 0
  423. };
  424. int nrlt = (sizeof(rltab) / sizeof(struct keytab));
  425.  
  426. /* Incomplete File Disposition table */
  427. static
  428. struct keytab ifdtab[] = {
  429.     "discard",   0, 0,
  430.     "keep",      1, 0
  431. };
  432.  
  433. /* SET TAKE parameters table */
  434. static
  435. struct keytab taktab[] = {
  436.     "echo",  0, 0,
  437.     "error", 1, 0,
  438.     "off",   2, CM_INV,            /* For compatibility */
  439.     "on",    3, CM_INV            /* with MS-DOS Kermit... */
  440. };
  441.  
  442. /* SET MACRO parameters table */
  443. static
  444. struct keytab smactab[] = {
  445.     "echo",  0, 0,
  446.     "error", 1, 0
  447. };
  448.  
  449. #ifndef NOSCRIPT
  450. static
  451. struct keytab scrtab[] = {
  452.     "echo",  0, 0
  453. };
  454. #endif /* NOSCRIPT */
  455.  
  456. /* Bytesize table */
  457. struct keytab byttab[] = {
  458.     "bytesize",  0, 0
  459. };
  460. int nbytt = 1;
  461.  
  462. #ifndef NOSERVER
  463. /* Server parameters table */
  464. struct keytab srvtab[] = {
  465.     "display", XYSERD, 0,
  466.     "timeout", XYSERT, 0
  467. };
  468. #endif /* NOSERVER */
  469.  
  470. /* SET TRANSFER/XFER table */
  471.  
  472. struct keytab tstab[] = {
  473. #ifdef XFRCAN
  474. /*
  475.   This should be propogated to all versions...
  476. */
  477.     "cancellation",   0,   0,
  478. #endif /* XFRCAN */
  479. #ifndef NOCSETS
  480.     "character-set", 1,   0,
  481. #endif /* NOCSETS */
  482.     "locking-shift", 2,   0
  483. };
  484. int nts = (sizeof(tstab) / sizeof(struct keytab));
  485.  
  486. #ifndef NOCSETS
  487. /* SET TRANSFER CHARACTER-SET table */
  488.  
  489. extern struct keytab tcstab[];
  490. extern int ntcs;
  491. #endif /* NOCSETS */
  492.  
  493. /* SET TRANSFER LOCKING-SHIFT table */
  494. struct keytab lstab[] = {
  495.     "forced", 2,   0,
  496.     "off",    0,   0,
  497.     "on",     1,   0
  498. };
  499. int nls = (sizeof(lstab) / sizeof(struct keytab));
  500.  
  501. /* SET TELNET table */
  502. #ifdef TNCODE
  503. extern int tn_duplex, tn_nlm;
  504. extern char *tn_term;
  505. struct keytab tntab[] = {
  506.     "echo",          CK_TN_EC,   0,
  507.     "newline-mode",  CK_TN_NL,   0,
  508.     "terminal-type", CK_TN_TT,   0
  509. };
  510. int ntn = (sizeof(tntab) / sizeof(struct keytab));
  511. #endif /* TNCODE */
  512.  
  513. struct keytab ftrtab[] = {        /* Feature table */
  514. #ifndef NOCSETS                /* 0 = we have it, 1 = we don't */
  515. "character-sets",    0, 0,
  516. #else
  517. "character-sets",    1, 0,
  518. #endif /* NOCSETS */
  519. #ifndef NOCYRIL
  520. "cyrillic",        0, 0,
  521. #else
  522. "cyrillic",        1, 0,
  523. #endif /* NOCYRIL */
  524.  
  525. #ifndef NODEBUG
  526. "debug",        0, 0,
  527. #else
  528. "debug",        1, 0,
  529. #endif /* NODEBUG */
  530.  
  531. #ifndef NODIAL
  532. "dial",            0, 0,
  533. #else
  534. "dial",            1, 0,
  535. #endif /* NODIAL */
  536.  
  537. #ifdef DYNAMIC
  538. "dynamic-memory",       0, 0,
  539. #else
  540. "dynamic-memory",       1, 0,
  541. #endif /* DYNAMIC */
  542.  
  543. #ifdef CK_CURSES
  544. "fullscreen-display",    0, 0,
  545. #else
  546. "fullscreen-display",    1, 0,
  547. #endif /* CK_CURSES */
  548. #ifdef HEBREW
  549. "hebrew",               0, 0,
  550. #else
  551. "hebrew",               1, 0,
  552. #endif /* HEBREW */
  553. #ifndef NOHELP
  554. "help",            0, 0,
  555. #else
  556. "help",            1, 0,
  557. #endif /* NOHELP */
  558. #ifndef NOSPL
  559. "if-command",        0, 0,
  560. #else
  561. "if-command",        1, 0,
  562. #endif /* NOSPL */
  563. #ifndef NOJC
  564. #ifdef UNIX
  565. "job-control",        0, 0,
  566. #else
  567. "job-control",        1, 0,
  568. #endif /* UNIX */
  569. #else
  570. "job-control",        1, 0,
  571. #endif /* NOJC */
  572. #ifdef KANJI
  573. "kanji",        0, 0,
  574. #else
  575. "kanji",        1, 0,
  576. #endif /* KANJI */
  577. #ifndef NOCSETS
  578. "latin1",        0, 0,
  579. #else
  580. "latin1",        1, 0,
  581. #endif /* NOCSETS */
  582. #ifdef LATIN2
  583. "latin2",        0, 0,
  584. #else
  585. "latin2",        1, 0,
  586. #endif /* LATIN2 */
  587. #ifdef NETCONN
  588. "network",        0, 0,
  589. #else
  590. "network",        1, 0,
  591. #endif /* NETCONN */
  592. #ifndef NOPUSH
  593. "push",            0, 0,
  594. #else
  595. "push",            1, 0,
  596. #endif /* PUSH */
  597. #ifndef NOSCRIPT
  598. "script-command",    0, 0,
  599. #else
  600. "script-command",    1, 0,
  601. #endif /* NOSCRIPT */
  602. #ifndef NOSERVER
  603. "server-mode",        0, 0,
  604. #else
  605. "server-mode",        1, 0,
  606. #endif /* NOSERVER */
  607. #ifndef NOSHOW
  608. "show-command",        0, 0,
  609. #else
  610. "show-command",        1, 0,
  611. #endif /* NOSHOW */
  612. #ifndef NOXMIT
  613. "transmit",        0, 0,
  614. #else
  615. "transmit",        1, 0
  616. #endif /* NOXMIT */
  617. };
  618. int nftr = (sizeof(ftrtab) / sizeof(struct keytab));
  619.  
  620. int                    /* CHECK command */
  621. dochk() {
  622.     int x, y;
  623.     if ((y = cmkey(ftrtab,nftr,"","",xxstring)) < 0) return(y);
  624.     if ((x = cmcfm()) < 0) return(x);
  625.     if (msgflg)                /* If at top level... */
  626.       printf(" %svailable\n", y ? "Not a" : "A"); /* Print a message */
  627.     else if (y && !backgrd)        /* Or if not available and in */
  628.       printf(" CHECK: feature not available\n"); /* command file or macro */
  629.     return(success = 1 - y);
  630. }
  631.  
  632. #ifndef MAC
  633. #ifndef NOSETKEY
  634. int
  635. set_key() {                /* SET KEY */
  636.     int y;
  637.     int kc;                /* Key code */
  638.     char *bind;                /* Key binding */
  639.  
  640.     if ((y = cmnum("numeric key code","",10,&kc,xxstring)) < 0)
  641.       return(y);
  642.     if (kc < 0 || kc >= KMSIZE) {
  643.     printf("?key code must be between 0 and %d\n", KMSIZE - 1);
  644.     return(-9);
  645.     }
  646. #ifdef OS2
  647.     wideresult = -1;
  648. #endif /* OS2 */
  649.     if ((y = cmtxt("key definition","",&bind,xxstring)) < 0)
  650.       return(y);
  651.     if (macrotab[kc]) {            /* Possibly free old macro from key */
  652.     free(macrotab[kc]);
  653.     macrotab[kc] = NULL;
  654.     }
  655.     switch (strlen(bind)) {        /* Action depends on length */
  656. #ifdef OS2
  657.       case 0:                /* Reset to default binding */
  658.         keymap[kc] = wideresult == -1 ? kc : 0;   /* or bind to NUL */
  659.     break;
  660.       case 1:                /* Single character */
  661.     keymap[kc] = wideresult == -1 ? (CHAR) *bind : wideresult;
  662.     break;
  663. #else /* Not OS/2 */
  664.       case 0:                /* Reset to default binding */
  665.     keymap[kc] = kc;
  666.     break;
  667.       case 1:                /* Single character */
  668.       keymap[kc] = (CHAR) *bind;
  669.       break;
  670. #endif /* OS2 */
  671.  
  672.       default:                /* Character string */
  673.     keymap[kc] = kc;
  674.     macrotab[kc] = (MACRO) malloc(strlen(bind)+1);
  675.     if (macrotab[kc])
  676.       strcpy((char *) macrotab[kc], bind);
  677.     break;
  678.     }
  679.     return(1);
  680. }
  681. #endif /* NOSETKEY */
  682. #endif /* MAC */
  683.  
  684. /*  D O P R M  --  Set a parameter.  */
  685. /*
  686.  Returns:
  687.   -2: illegal input
  688.   -1: reparse needed
  689.    0: success
  690. */
  691. int
  692. doprm(xx,rmsflg) int xx, rmsflg; {
  693.     int i, x, y = 0, z;
  694.     long zz;
  695.     char *s;
  696.  
  697. switch (xx) {
  698.  
  699. #ifdef SUNX25                /* SET X25 ... */
  700. case XYX25:
  701.     return(setx25());
  702.  
  703. case XYPAD:                /* SET PAD ... */
  704.     return(setpadp());
  705. #endif /* SUNX25 */
  706.  
  707. case XYEOL:    /* These have all been moved to set send/receive... */
  708. case XYLEN:     /* Let the user know what to do. */
  709. case XYMARK:
  710. case XYNPAD:
  711. case XYPADC:
  712. case XYTIMO:
  713.     printf("...Use SET SEND or SET RECEIVE instead.\n");
  714.     printf("Type HELP SET SEND or HELP SET RECEIVE for more info.\n");
  715.     return(success = 0);
  716.  
  717. case XYATTR:                /* File Attribute packets */
  718.     return(setat(rmsflg));
  719.  
  720. case XYIFD:                /* Incomplete file disposition */
  721.     if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
  722.     if ((x = cmcfm()) < 0) return(x);
  723.     if (rmsflg) {
  724.     sstate = setgen('S', "310", y ? "1" : "0", "");
  725.     return((int) sstate);
  726.     } else {
  727.     keep = y;
  728.     return(success = 1);
  729.     }
  730.  
  731. #ifndef NOSPL
  732. case XYINPU:                /* SET INPUT */
  733.     return(setinp());
  734. #endif /* NOSPL */
  735.  
  736. #ifdef NETCONN
  737. case XYNET:                /* SET NETWORK */
  738.     if ((z = cmkey(netcmd,nnets,"","tcp/ip",xxstring)) < 0)
  739.       return(z);
  740.     if ((x = cmcfm()) < 0) return(x);
  741.     nettype = z;
  742.     if (
  743.     (nettype != NET_DEC) &&
  744.     (nettype != NET_SX25) &&
  745.         (nettype != NET_TCPB)) {
  746.     printf("?Network type not supported\n");
  747.     return(success = 0);
  748.     } else {
  749.     return(success = 1);
  750.     }
  751. #endif /* NETCONN */
  752.  
  753. case XYHOST:                /* SET HOST or SET LINE */
  754. case XYLINE:
  755.     return(setlin(xx,1));
  756.  
  757. #ifndef MAC
  758. #ifndef NOSETKEY
  759. case XYKEY:                /* SET KEY */
  760.     return(set_key());
  761. #endif /* NOSETKEY */
  762. #endif /* MAC */
  763.  
  764. #ifndef NOCSETS
  765. case XYLANG:                 /* Language */
  766.     if ((y = cmkey(lngtab,nlng,"","none",xxstring)) < 0) /* language code */
  767.       return(y);
  768.     if ((x = cmcfm()) < 0) return(x);    /* And confirmation of command */
  769.  
  770.     /* Look up language and get associated character sets */
  771.     for (i = 0; (i < nlangs) && (langs[i].id != y); i++) ;
  772.     if (i >= nlangs) {
  773.     printf("?internal error, sorry\n");
  774.     return(success = 0);
  775.     }
  776.     language = i;            /* All good, set the language, */
  777.     return(success = 1);
  778. #endif /* NOCSETS */
  779.  
  780. #ifndef MAC
  781. case XYBACK:                /* BACKGROUND */
  782.     if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
  783.     if ((y = cmcfm()) < 0) return(y);
  784.     bgset = z;
  785.     success = 1;
  786.     bgchk();
  787.     return(success);
  788. #endif /* MAC */
  789.  
  790. case XYQUIE:                /* QUIET */
  791.     return(success = seton(&quiet));
  792.  
  793. case XYBUF: {                /* BUFFERS */
  794. #ifdef DYNAMIC
  795.     int sb, rb;
  796.     if ((y = cmnum("send buffer size","",10,&sb,xxstring)) < 0) {
  797.     if (y == -3) printf("?two numbers required\n");
  798.     return(y);
  799.     }
  800.     if (sb < 80) {
  801.     printf("?too small");
  802.     return(-2);
  803.     }
  804.     if ((y = cmnum("receive buffer size","",10,&rb,xxstring)) < 0)  {
  805.     if (y == -3) printf("?receive buffer size required\n");
  806.     return(y);
  807.     }
  808.     if (rb < 80) {
  809.     printf("?too small");
  810.     return(-2);
  811.     }
  812.     if ((y = cmcfm()) < 0) return(y);
  813.     if ((y = inibufs(sb,rb)) < 0) return(y);
  814.     y = adjpkl(urpsiz,wslotr,bigrbsiz); /* Maybe adjust packet sizes */
  815.     if (y != urpsiz) urpsiz = y;
  816.     y = adjpkl(spsiz,wslotr,bigsbsiz);
  817.     if (y != spsiz) spsiz = spmax = spsizr = y;
  818.     return(success = 1);
  819. #else
  820.     printf("?Sorry, not available\n");
  821.     return(success = 0);
  822. #endif /* DYNAMIC */
  823. }
  824.  
  825. case XYCHKT:                /* BLOCK-CHECK */
  826.     if ((x = cmkey(chktab,4,"","1",xxstring)) < 0) return(x);
  827.     if ((y = cmcfm()) < 0) return(y);
  828.     bctr = x;                 /* Set locally too, even if REMOTE SET */
  829.     if (rmsflg) {
  830.     if (x == 4) {
  831.         tmpbuf[0] = 'B';
  832.         tmpbuf[1] = '\0';
  833.     } else sprintf(tmpbuf,"%d",x);
  834.     sstate = setgen('S', "400", tmpbuf, "");
  835.     return((int) sstate);
  836.     } else {
  837.     return(success = 1);
  838.     }
  839.  
  840. #ifndef MAC
  841. /*
  842.   The Mac has no carrier...
  843. */
  844. case XYCARR:                /* CARRIER */
  845.     if ((y = cmkey(crrtab,ncrr,"","auto",xxstring)) < 0) return(y);
  846.     if (y == CAR_ON) {
  847.     x = cmnum("Carrier wait timeout, seconds","0",10,&z,xxstring);
  848.     if (x < 0) return(z);
  849.     }
  850.     if ((x = cmcfm()) < 0) return(x);
  851.     carrier = ttscarr(y);
  852.     cdtimo = z;
  853.     return(success = 1);
  854. #endif /* MAC */
  855.  
  856. #ifdef TNCODE
  857. case XYTEL:                /* TELNET */
  858.     if ((z = cmkey(tntab,ntn,"parameter for TELNET negotiations", "",
  859.            xxstring)) < 0) return(z);
  860.     switch (z) {
  861.       case CK_TN_EC:            /* ECHO */
  862.     if ((x = cmkey(rltab,nrlt,
  863.                "initial TELNET echoing state","local",xxstring)) < 0)
  864.       return(x);
  865.     if ((y = cmcfm()) < 0) return(y);
  866.     tn_duplex = x;
  867.     return(success = 1);
  868.  
  869.       case CK_TN_TT:            /* TERMINAL TYPE */
  870.     if ((y = cmtxt("terminal type for TELNET connections","",
  871.                &s,xxstring)) < 0)
  872.       return(y);
  873.     if (tn_term) free(tn_term);    /* Free any previous storage */
  874.     if (s == NULL || *s == NUL) {    /* If none given */
  875.         tn_term = NULL;        /* remove the override string */
  876.         return(success = 1);
  877.     } else if (tn_term = malloc(strlen(s)+1)) { /* Make storage for new */
  878.         strcpy(tn_term,s);        /* Copy string into new storage */
  879.         return(success = 1);
  880.     } else return(success = 0);
  881.  
  882.       case CK_TN_NL:            /* NEWLINE-MODE */
  883.     return(success = seton(&tn_nlm));
  884.  
  885.       default:
  886.     return(-2);
  887.     }
  888. #endif /* TNCODE */
  889.  
  890. default:
  891.     break;
  892. }
  893.  
  894. switch (xx) {
  895. #ifndef NOSPL
  896. case XYCOUN:                /* SET COUNT */
  897.     x = cmnum("Positive number","0",10,&z,xxstring);
  898.     if (x < 0) return(x);
  899.     if ((x = cmcfm()) < 0) return(x);
  900.     if (z < 0) {
  901.     printf("?A positive number, please\n");
  902.     return(0);
  903.     }
  904.     debug(F101,"XYCOUN: z","",z);
  905.     return(success = setnum(&count[cmdlvl],z,0,10000));
  906. #endif /* NOSPL */
  907.  
  908. #ifndef NOSPL
  909. case XYCASE:
  910.     return(success = seton(&inpcas[cmdlvl]));
  911. #endif /* NOSPL */
  912.  
  913. case XYCMD:                /* COMMAND ... */
  914.     if ((y = cmkey(byttab,nbytt,"","bytesize",xxstring)) < 0) return(y);
  915.     if ((y = cmnum("bytesize for command characters, 7 or 8","7",10,&x,
  916.            xxstring)) < 0)
  917.       return(y);
  918.     if (x != 7 && x != 8) {
  919.     printf("\n?The choices are 7 and 8\n");
  920.     return(success = 0);
  921.     }
  922.     if ((y = cmcfm()) < 0) return(y);
  923.     if (x == 7) cmdmsk = 0177;
  924.     else if (x == 8) cmdmsk = 0377;
  925.     return(success = 1);
  926.     
  927. case XYDFLT:                /* SET DEFAULT = CD */
  928.     return(success = docd());
  929.  
  930. case XYDEBU:                /* SET DEBUG { on, off, session } */
  931.     if ((y = cmkey(dbgtab,ndbg,"","",xxstring)) < 0) return(y);
  932.     if ((x = cmcfm()) < 0) return(x);
  933.     switch (y) {
  934.       case 0:                /* 0 = all debugging off. */
  935.     debses = 0;
  936. #ifdef DEBUG
  937.     if (deblog) doclslog(LOGD);
  938. #endif /* DEBUG */
  939.         return(success = 1);
  940.  
  941.       case 1:                /* 1 = log debugging to debug.log */
  942. #ifdef DEBUG
  943.     deblog = debopn("debug.log", 0);
  944.     return(success = deblog ? 1 : 0);
  945. #else
  946.     printf("?Sorry, debug log feature not enabled\n");
  947.     return(success = 0);
  948. #endif /* DEBUG */
  949.  
  950.       case 2:                /* 2 = session. */
  951.     return(success = debses = 1);
  952.     }
  953.  
  954. case XYDELA:                /* SET DELAY */
  955.     y = cmnum("Number of seconds before starting to send","5",10,&x,xxstring);
  956.     if (x < 0) x = 0;
  957.     return(success = setnum(&delay,x,y,999));
  958.  
  959. default:
  960.     break;
  961. }
  962.  
  963. switch (xx) {
  964.  
  965. #ifndef NODIAL
  966. case XYDIAL:                /* SET DIAL */
  967.     return(setdial());
  968. #endif /* NODIAL */
  969.  
  970. #ifdef COMMENT                /* Unused at present */
  971. case XYDOUB:
  972.     if ((x = cmfld("Character to double","none",&s,xxstring)) < 0) {
  973.     if (x == -3) {
  974.         dblchar = -1;
  975.         if (msgflg) printf("Doubling Off\n");
  976.         return(success = 1);
  977.     } else return(x);
  978.     }
  979.     strcpy(line,s);
  980.     lp = line;
  981.     if ((x = cmcfm()) < 0) return(x);
  982.     if (!xxstrcmp(lp,"none",4)) {
  983.     dblchar = -1;
  984.     if (msgflg) printf("Doubling Off\n");
  985.     return(success = 1);
  986.     }
  987.     if ((int)strlen(lp) != 1) return(-2);
  988.     dblchar = *lp & 0xFF;
  989.     if (msgflg) printf("Doubled: %d\n",dblchar);
  990.     return(success = 1);
  991. #endif /* COMMENT */
  992.  
  993. case XYDUPL:                /* SET DUPLEX */
  994.     if ((y = cmkey(dpxtab,2,"","full",xxstring)) < 0) return(y);
  995.     if ((x = cmcfm()) < 0) return(x);
  996.     duplex = y;
  997.     return(success = 1);
  998.  
  999. case XYLCLE:                /* LOCAL-ECHO (= DUPLEX) */
  1000.     return(success = seton(&duplex));
  1001.  
  1002. case XYESC:                /* SET ESCAPE */
  1003.     sprintf(tmpbuf,"%d",DFESC);
  1004.     y = cmnum("Decimal ASCII code for CONNECT-mode escape character",
  1005.           tmpbuf, 10,&x,xxstring);
  1006.     success = setcc(&escape,x,y);
  1007. #ifdef COMMENT
  1008. /* This is what SHOW ESCAPE is for. */
  1009.     if (success && msgflg)
  1010.       printf(" CONNECT-mode escape character: %d (Ctrl-%c, %s)\n",
  1011.          escape,ctl(escape),(escape == 127 ? "DEL" : ccntab[escape]));
  1012. #endif /* COMMENT */
  1013.     return(success);
  1014.  
  1015. default:
  1016.     break;
  1017. }
  1018.  
  1019. switch (xx) {
  1020. case XYFILE:                /* SET FILE */
  1021.     return(setfil(rmsflg));
  1022.  
  1023. case XYFLOW:                /* FLOW-CONTROL */
  1024. /*
  1025.   Note: flotab[] keyword table (defined above) only includes the legal 
  1026.   flow-control options for each implementation, controlled by symbols
  1027.   defined in ckcdeb.h.
  1028. */
  1029.     if ((y = cmkey(flotab,nflo,"","xon/xoff",xxstring)) < 0) return(y);
  1030.     if ((x = cmcfm()) < 0) return(x);
  1031.     flow = y;
  1032. #ifdef CK_SPEED
  1033.     if (flow == FLO_XONX)        /* Xon/Xoff forces prefixing */
  1034.       ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1;
  1035. #endif /* CK_SPEED */
  1036.     debug(F101,"set flow","",flow);
  1037.     return(success = 1);
  1038.  
  1039. case XYHAND:                /* HANDSHAKE */
  1040.     if ((y = cmkey(hshtab,nhsh,"","none",xxstring)) < 0) return(y);
  1041.     if (y == 998) {
  1042.     if ((x = cmnum("ASCII value","",10,&y,xxstring)) < 0)
  1043.       return(x);
  1044.     if ((y < 1) || ((y > 31) && (y != 127))) {
  1045.         printf("?Character must be in ASCII control range\n");
  1046.         return(-9);
  1047.     }
  1048.     }
  1049.     if ((x = cmcfm()) < 0) return(x);
  1050.     turn = (y > 0127) ? 0 : 1 ;
  1051.     turnch = y;
  1052.     return(success = 1);
  1053.  
  1054. #ifndef NOSPL
  1055. case XYMACR:                /* SET MACRO */
  1056.     if ((y = cmkey(smactab,2,"","",xxstring)) < 0) return(y);
  1057.     switch (y) {
  1058.       case 0: return(success = seton(&mecho));
  1059.       case 1: return(success = seton(&merror[cmdlvl]));
  1060.       default: return(-2);
  1061.     }
  1062. #endif /* NOSPL */
  1063.  
  1064. #ifndef NODIAL
  1065. case XYMODM:                /* SET MODEM */
  1066.     if ((x = cmkey(mdmtab,nmdm,"type of modem","none", xxstring)) < 0)
  1067.     return(x);
  1068.     if ((z = cmcfm()) < 0) return(z);
  1069.     mdmtyp = x;
  1070. #ifndef MINIDIAL
  1071.     tbmodel = 0;          /* If it's a Telebit, we don't know the model yet */
  1072. #endif /* MINIDIAL */
  1073.     return(success = 1);
  1074. #endif /* NODIAL */
  1075.  
  1076.   case XYMSGS:
  1077. #ifdef VMS
  1078.     if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
  1079.     if ((y = cmcfm()) < 0) return(y);
  1080.     vms_msgs = z;
  1081.     printf("Sorry, SET MESSAGES not implemented yet\n");
  1082.     return(success = 0);
  1083. #endif /* VMS */
  1084. default:
  1085.     break;
  1086. }
  1087.  
  1088. switch (xx) {
  1089.     
  1090. case XYPARI:                /* PARITY */
  1091.     if ((y = cmkey(partab,npar,"","none",xxstring)) < 0) return(y);
  1092.     if ((x = cmcfm()) < 0) return(x);
  1093.  
  1094. /* If parity not none, then we also want 8th-bit prefixing */
  1095.  
  1096.     if (parity = y) ebqflg = 1; else ebqflg = 0;
  1097.     return(success = 1);
  1098.  
  1099. #ifndef NOFRILLS
  1100. case XYPROM:                /* SET PROMPT */
  1101. /*
  1102.   Note: xxstring not invoked here.  Instead, it is invoked every time the
  1103.   prompt is issued.  This allows the prompt string to contain variables
  1104.   that can change, like \v(dir), \v(time), etc.
  1105. */
  1106. #ifdef MAC
  1107.     if ((x = cmtxt("Program's command prompt","Mac-Kermit>",&s,NULL)) < 0)
  1108. #else
  1109.     if ((x = cmtxt("Program's command prompt","C-Kermit>",&s,NULL)) < 0)
  1110. #endif /* MAC */
  1111.       return(x);
  1112.     if (*s == '{') {            /* Remove enclosing braces, if any */
  1113.     x = (int)strlen(s);
  1114.     if (s[x-1] == '}') {
  1115.         s[x-1] = NUL;
  1116.         s++;
  1117.     }
  1118.     }
  1119. #ifdef COMMENT
  1120. /*
  1121.   Let's not do this any more -- we don't do it anywhere else.
  1122. */
  1123.     else if (*s == '"') {        /* For compatibility with pre-5A */
  1124.     x = (int)strlen(s);
  1125.     if (s[x-1] == '"') {
  1126.         s[x-1] = NUL;
  1127.         s++;
  1128.     }
  1129.     }
  1130. #endif /* COMMENT */
  1131.     cmsetp(s);                /* Set the prompt */
  1132.     return(success = 1);
  1133. #endif /* NOFRILLS */
  1134.  
  1135. case XYRETR:                /* RETRY: per-packet retry limit */
  1136.     y = cmnum("Maximum retries per packet","10",10,&x,xxstring);
  1137.     if (x < 0) x = 0;
  1138.     if ((x = setnum(&maxtry,x,y,999)) < 0) return(x);
  1139.     if (maxtry <= wslotr) {
  1140.     printf("?Retry limit must be greater than window size\n");
  1141.     return(success = 0);
  1142.     }
  1143.     sprintf(tmpbuf,"%d",maxtry);
  1144.     if (rmsflg) {
  1145.     sstate = setgen('S', "403", tmpbuf, "");
  1146.     return((int) sstate);
  1147.     } else return(success = x);
  1148.  
  1149. #ifndef NOSERVER
  1150. case XYSERV:                /* SET SERVER items */
  1151.     if ((y = cmkey(srvtab,2,"","",xxstring)) < 0) return(y);
  1152.     switch (y) {
  1153.       case XYSERT:
  1154.     tp = tmpbuf;
  1155.         sprintf(tp,"%d",DSRVTIM);
  1156.     if ((y = cmnum("interval for server NAKs, 0 = none",tp,10,&x,
  1157.                xxstring)) < 0)
  1158.       return(y);
  1159.     if (x < 0) {
  1160.         printf("\n?Specify a positive number, or 0 for no server NAKs\n");
  1161.         return(0);
  1162.     }
  1163.     if ((y = cmcfm()) < 0) return(y);
  1164.     sprintf(tp,"%d",x);
  1165.     if (rmsflg) {
  1166.         sstate = setgen('S', "404", tp, "");
  1167.         return((int) sstate);
  1168.     } else {
  1169.         srvtim = x;            /* Set the server timeout variable */
  1170.         return(success = 1);
  1171.     }
  1172.       case XYSERD:            /* SERVER DISPLAY */
  1173.     return(success = seton(&srvdis)); /* ON or OFF... */
  1174.       default:
  1175.     return(-2);
  1176.     }
  1177. #endif /* NOSERVER */
  1178.  
  1179. #ifdef UNIX
  1180. #ifndef NOJC
  1181. case XYSUSP:                /* SET SUSPEND */
  1182.     seton(&suspend);            /* on or off... */
  1183.     return(success = 1);
  1184. #endif /* NOJC */
  1185. #endif /* UNIX */
  1186.  
  1187. case XYTAKE:                /* SET TAKE */
  1188.     if ((y = cmkey(taktab,4,"","",xxstring)) < 0) return(y);
  1189.     switch (y) {
  1190.       case 0: return(success = seton(&techo));
  1191. #ifndef NOSPL
  1192.       case 1: return(success = seton(&takerr[cmdlvl]));
  1193. #else
  1194.       case 1: return(success = seton(&takerr[tlevel]));
  1195. #endif /* NOSPL */
  1196.       case 2: techo = 0; return(success = 1); /* For compatibility with */
  1197.       case 3: techo = 1; return(success = 1); /* MS-DOS Kermit */
  1198.       default: return(-2);
  1199.     }
  1200.  
  1201. #ifndef NOSCRIPT
  1202. case XYSCRI:                /* SET SCRIPT */
  1203.     if ((y = cmkey(scrtab,1,"","echo",xxstring)) < 0) return(y);
  1204.     switch (y) {
  1205.       case 0: return(success = seton(&secho));
  1206.       default: return(-2);
  1207.     }
  1208. #endif /* NOSCRIPT */
  1209.  
  1210. default:
  1211.     break;
  1212. }
  1213.  
  1214. switch (xx) {
  1215. case XYTERM:                /* SET TERMINAL */
  1216.     return(settrm());
  1217.  
  1218. default:
  1219.     break;
  1220. }
  1221.  
  1222. switch (xx) {
  1223.  
  1224. /* SET SEND/RECEIVE protocol parameters. */
  1225.  
  1226. case XYRECV:
  1227. case XYSEND:
  1228.     return(setsr(xx,rmsflg));
  1229.  
  1230. #ifdef UNIX
  1231. case XYSESS:                /* SESSION-LOG */
  1232.     if ((x = cmkey(fttab,2,"type of file","text",xxstring)) < 0)
  1233.       return(x);
  1234.     if ((y = cmcfm()) < 0) return(y);
  1235.     sessft = x;
  1236.     return(success = 1);
  1237. #endif /* UNIX */
  1238.  
  1239. case XYSPEE:                /* SET SPEED */
  1240.     if (network) {
  1241.     printf("\n?Speed cannot be set for network connections\n");
  1242.     return(success = 0);
  1243.     }
  1244.     lp = line;
  1245.     sprintf(lp,"Transmission rate for %s in bits per second",ttname);
  1246.  
  1247.     if ((x = cmkey(spdtab,nspd,line,"",xxstring)) < 0) {
  1248.     if (x == -3) printf("?value required\n");
  1249.     return(x);
  1250.     }
  1251.     if ((y = cmcfm()) < 0) return(y);
  1252.     if (!local) {
  1253.     printf("?Sorry, you must SET LINE first\n");
  1254.     return(success = 0);
  1255.     }
  1256.     zz = (long) x * 10L;
  1257.     if (zz == 70) zz = 75;        /* (see spdtab[] def) */
  1258.     if (ttsspd(x) < 0)  {        /* Call ttsspd with cps, not bps! */
  1259.     printf("?Unsupported line speed - %ld\n",zz);
  1260.     return(success = 0);
  1261.     } else {
  1262.     speed = zz;
  1263.     if (pflag &&
  1264. #ifndef NOSPL
  1265.         cmdlvl == 0
  1266. #else
  1267.         tlevel < 0
  1268. #endif /* NOSPL */
  1269.         ) {
  1270.         if (speed == 8880)
  1271.           printf("%s, 75/1200 bps\n",ttname);
  1272.         else
  1273.           printf("%s, %ld bps\n",ttname,speed);
  1274.     }
  1275.     return(success = 1);
  1276.     }
  1277.  
  1278.   case XYXFER:                /* SET TRANSFER */
  1279.     if ((y = cmkey(tstab,nts,"","character-set",xxstring)) < 0) return(y);
  1280. #ifdef XFRCAN
  1281.     if (y == 0) {            /* CANCELLATION */
  1282.     if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
  1283.     if (z == 0) {            /* OFF */
  1284.         if ((y = cmcfm()) < 0) return(y);
  1285.         xfrcan = 0;
  1286.     } else {
  1287.         if ((y = cmnum("ASCII code for cancellation character","3",10,&x,
  1288.                xxstring)) < 0)
  1289.           return(y);
  1290.         if (x > 31 && x != 127) {
  1291.         printf("Cancel character must be in ASCII control range\n");
  1292.         return(-9);
  1293.         }
  1294.         if ((y = cmnum("How many required to cause cancellation",
  1295.                "2",10,&z, xxstring)) < 0)
  1296.           return(y);
  1297.         if (z < 2) {
  1298.         printf("Number must be 2 or greater\n");
  1299.         return(-9);
  1300.         }
  1301.         if ((y = cmcfm()) < 0) return(y);
  1302.         xfrcan = 1;            /* CANCELLATION ON */
  1303.         xfrchr = x;            /* Using this character */
  1304.         xfrnum = z;            /* Needing this many of them */
  1305.     }
  1306.     return(success = 1);
  1307.     } else
  1308. #endif /* XFERCAN */
  1309. #ifndef NOCSETS
  1310.       if (y == 1) {            /* CHARACTER-SET */
  1311.     if ((y = cmkey(tcstab,ntcs,"","transparent",xxstring)) < 0) return(y);
  1312.     if ((x = cmcfm()) < 0) return(x);
  1313.     if (rmsflg) {
  1314.         sstate = setgen('S', "405", tcsinfo[y].designator, "");
  1315.         return((int) sstate);
  1316.     } else {
  1317.         tslevel = (y == TC_TRANSP) ? 0 : 1; /* transfer syntax level */
  1318.         tcharset = y;        /* transfer character set */
  1319.         return(success = 1);
  1320.     }
  1321.     } else
  1322. #endif /* NOCSETS */
  1323.       if (y == 2) {            /* LOCKING-SHIFT */
  1324.       if ((y = cmkey(lstab,nls,"","on",xxstring)) < 0)
  1325.         return(y);
  1326.       if ((x = cmcfm()) < 0) return(x);
  1327.       lscapr = (y == 1) ? 1 : 0;    /* ON: requested = 1 */
  1328.       lscapu = (y == 2) ? 2 : 0;    /* FORCED:  used = 1 */
  1329.       return(success = 1);
  1330.       } else return(-2);
  1331.  
  1332. #ifndef NOXMIT
  1333.   case XYXMIT:                /* SET TRANSMIT */
  1334.     return(setxmit());
  1335. #endif /* NOXMIT */
  1336.  
  1337. #ifndef NOCSETS
  1338.   case XYUNCS:                /* UNKNOWN-CHARACTER-SET */
  1339.     if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
  1340.     if ((x = cmcfm()) < 0) return(x);
  1341.     unkcs = y;
  1342.     return(success = 1);
  1343. #endif /* NOCSETS */
  1344.  
  1345. #ifdef UNIX
  1346.   case XYWILD:                /* WILDCARD-EXPANSION */
  1347.     if ((y = cmkey(wildtab,2,"who expands wildcards","kermit",xxstring)) < 0)
  1348.       return(y);
  1349.     if ((x = cmcfm()) < 0) return(x);
  1350.     wildxpand = y;
  1351.     return(success = 1);
  1352. #endif /* UNIX */
  1353.  
  1354.   case XYWIND:                /* WINDOW-SLOTS */
  1355.     y = cmnum("Number of sliding-window slots, 1 to 31","1",10,&x,xxstring);
  1356.     y = setnum(&z,x,y,31);
  1357.     if (y < 0) return(y);
  1358.     if (z < 1) z = 1;
  1359. #ifdef COMMENT
  1360.     /* This is taken care of automatically now in protocol negotiation */
  1361.     if (maxtry < z) {
  1362.     printf("?Window slots must be less than retry limit\n");
  1363.     return(success = 0);
  1364.     }
  1365. #endif /* COMMENT */
  1366.     if (rmsflg) {            /* Set remote window size */
  1367.     tp = tmpbuf;
  1368.     sprintf(tp,"%d",z);
  1369.     sstate = setgen('S', "406", tp, "");
  1370.     return((int) sstate);
  1371.     }
  1372.     wslotr = z;                /* Set local window size */
  1373.     swcapr = (wslotr > 1) ? 1 : 0;    /* Set window bit in capas word? */
  1374.     if (wslotr > 1) {            /* Window size > 1? */
  1375.     y = adjpkl(urpsiz,wslotr,bigrbsiz); /* Maybe adjust packet size */
  1376.     if (y != urpsiz) {        /* Did it change? */
  1377.         urpsiz = y;
  1378.         if (msgflg)
  1379.         printf(
  1380. " Adjusting receive packet-length to %d for %d window slots\n",
  1381.            urpsiz, wslotr);
  1382.     }
  1383.     }
  1384.     return(success = 1);
  1385.  
  1386. #ifndef NOSPL
  1387.   case XYOUTP:                /* OUTPUT command parameters */
  1388.     if ((y = cmkey(outptab,1,"OUTPUT command parameter","pacing",
  1389.            xxstring)) < 0)
  1390.       return(y);
  1391.     switch(y) {                /* Which parameter */
  1392.       case 0:                /* PACING */
  1393.     y = cmnum("Milliseconds to pause between each OUTPUT character","100",
  1394.           10,&x,xxstring);
  1395.     y = setnum(&z,x,y,16383);    /* Verify and get confirmation */
  1396.     if (y < 0) return(y);
  1397.     if (z < 0) z = 0;        /* (save some space) */
  1398.     pacing = z;
  1399.     return(success = 1);    
  1400.       default:                /* (shouldn't happen) */
  1401.     return(-2);
  1402.     }
  1403. #endif /* NOSPL */
  1404.  
  1405. #ifdef CK_SPEED
  1406.   case XYQCTL: {
  1407.     short *p;
  1408.     int zz;
  1409.     if ((z = cmkey(ctltab,2, "control-character prefixing option",""
  1410.            ,xxstring)) < 0)  
  1411.       return(z);
  1412.  
  1413.     /* Make space for a temporary copy of the prefixing table */
  1414.  
  1415.     p = (short *)malloc(256 * sizeof(short));
  1416.     if (!p) {
  1417.     printf("?Internal error - malloc failure\n");
  1418.     return(-9);
  1419.     }
  1420.     for (i = 0; i < 256; i++) p[i] = ctlp[i]; /* Copy current table */
  1421.  
  1422.     switch(z) {
  1423.       case 0:                /* UNPREFIXED control character */
  1424.       case 1:                /* PREFIXED control character */
  1425.     while (1) {        /* Collect a list of numbers */
  1426.         if ((x = cmnum((z == 0) ?
  1427. "\n Numeric ASCII value of control character that needs NO prefix,\n\
  1428.  or the word \"all\", or carriage return to complete the list" :
  1429. "\n Numeric ASCII value of control character that MUST BE prefixed,\n\
  1430.  or the word \"all\", or carriage return to complete the list",
  1431.                "",10,&y,xxstring
  1432.                )) < 0) {
  1433.         if (x == -3)
  1434.           break;
  1435.         if (x == -2) {
  1436.             if (p) free(p);
  1437.             debug(F110,"SET CONTROL atmbuf",atmbuf,0);
  1438.             if (!xxstrcmp(atmbuf,"all",3) ||
  1439.             !xxstrcmp(atmbuf,"al",2) ||
  1440.             !xxstrcmp(atmbuf,"a",1)) {
  1441.             if ((x = cmcfm()) < 0) /* Get confirmation */
  1442.               return(x);
  1443.             /* Set all values, but don't touch 0 */
  1444.             for (y = 1; y < 32; y++) ctlp[y] = z;
  1445.             for (y = 127; y < 160; y++) ctlp[y] = z;
  1446.             ctlp[255] = z;
  1447.             /* Watch out for XON and XOFF */
  1448.             if (flow == FLO_XONX && z == 0) {
  1449.                 if (msgflg) {
  1450.                 printf(
  1451. " XON/XOFF characters 17, 19, 145, 147 not affected.\n");
  1452.                 printf(
  1453. #ifdef CK_RTSCTS
  1454. " SET FLOW NONE or RTS/CTS to transmit these characters unprefixed.\n"
  1455. #else
  1456. " SET FLOW NONE to transmit these characters unprefixed.\n"
  1457. #endif /* CK_RTSCTS */
  1458.                        );
  1459.                 }
  1460.                 ctlp[XON] =
  1461.                   ctlp[XOFF] =
  1462.                 ctlp[XON+128] =
  1463.                   ctlp[XOFF+128] = 1;
  1464.             }
  1465. #ifdef TNCODE
  1466.             /* Watch out for TELNET IAC */
  1467.             if (network && (ttnproto == NP_TELNET) && z == 0) {
  1468.                 ctlp[255] = 1;
  1469.                 if (parity == 'e' || parity == 'm') ctlp[127] = 1;
  1470.                 if (msgflg)
  1471.                   printf(" TELNET IAC = 255 not affected.\n");
  1472.             }
  1473. #endif /* TNCODE */
  1474.             return(success = 1);
  1475.             } else {
  1476.             printf("?Please specify a number or the word ALL\n");
  1477.             return(-9);
  1478.             }
  1479.         } else {
  1480.             if (p) free(p);
  1481.             return(x);
  1482.         }
  1483.         }
  1484.         zz = 1 - z;
  1485.         if ((y >  31 && y < 127) ||    /* A specific numeric value */
  1486.         (y > 159 && y < 255) ||    /* Check that it is a valid */
  1487.         (y < zz) ||        /* control code. */
  1488.         (y > 255)) {
  1489.         printf("?Values allowed are: %d-31, 127-159, 255\n",zz);
  1490.         if (p) free(p);
  1491.         return(-9);
  1492.         }
  1493.         x = y & 127;        /* Get 7-bit value */
  1494.         if ((z == 0) &&        /* If they are saying it is safe... */
  1495.         (y == 0    ||        /* NUL = string terminator isn't */
  1496.          ((flow == FLO_XONX) &&    /* If flow control is Xon/Xoff */
  1497.           (x == XON || x == XOFF)) /* XON & XOFF chars not safe. */
  1498.          )) {
  1499.         if (msgflg)
  1500.           printf("Sorry, not while Xon/Xoff is in effect.\n");
  1501.         if (p) free(p);
  1502.         return(-9);
  1503.         }
  1504.         p[y] = z;            /* All OK, set flag */
  1505.     }                /* End of while loop */
  1506. /*
  1507.   Get here only if they have made no mistakes.  Copy temporary table back to
  1508.   permanent one, then free temporary table and return successfully.
  1509. */
  1510.     for (i = 0; i < 256; i++) ctlp[i] = p[i];
  1511.     if (p) free(p);
  1512.     return(success = 1);
  1513.       default:
  1514.     return(-2);
  1515.     }
  1516. }
  1517. #endif /* CK_SPEED */
  1518.  
  1519.   case XYREPT:
  1520.     if ((y = cmkey(rpttab,2,"repeat-count compression parameter","",xxstring))
  1521.     < 0)
  1522.       return(y);
  1523.     switch(y) {
  1524.       case 0:
  1525.     return(success = seton(&rptena)); /* REPEAT COUNTS = ON, OFF */
  1526.       case 1:                /* REPEAT MININUM number */
  1527.     printf("(not implemented yet, nothing happens)\n");
  1528.     return(-9);
  1529.       case 2:                /* REPEAT PREFIX char */
  1530.     if ((x = cmnum("ASCII value","",10,&z,xxstring)) < 0)
  1531.       return(x);
  1532.     if ((x = cmcfm()) < 0) return(x);
  1533.     if ((z > 32 && z < 63) || (z > 95 && z < 127)) {
  1534.         if (y == 1) rptmin = (CHAR) z; else myrptq = (CHAR) z;
  1535.         return(success = 1); 
  1536.     } else {
  1537.         printf("?Illegal value for prefix character\n");
  1538.         return(-9);
  1539.     }
  1540.     }
  1541.  
  1542. default:
  1543.     if ((x = cmcfm()) < 0) return(x);
  1544.     printf("Not working yet - %s\n",cmdbuf);
  1545.     return(success = 0);
  1546.     }
  1547. }
  1548.  
  1549. VOID
  1550. shoctl() {                /* SHOW CONTROL-PREFIXING */
  1551. #ifdef CK_SPEED
  1552.     int i, j, k;
  1553.     printf(
  1554. "\ncontrol quote = %d, applied to (0 = unprefixed, 1 = prefixed):\n\n",
  1555.        myctlq);
  1556.     for (i = 0; i < 16; i++) {
  1557.     printf("  %3d: %d   %3d: %d ",i,ctlp[i], i+16, ctlp[i+16]);
  1558.     if (i == 15)
  1559.       printf("  127: %d",ctlp[127]);
  1560.     else
  1561.       printf("        ");
  1562.     printf("  %3d: %d   %3d: %d ",i+128,ctlp[i+128], i+144, ctlp[i+144]);
  1563.     if (i == 15)  printf("  255: %d",ctlp[255]);
  1564.     printf("\n");
  1565.     }
  1566.     printf("\n");
  1567. #endif /* CK_SPEED */
  1568. }
  1569.  
  1570. #endif /* NOICP */
  1571.